package weeny.pre.renderer;

import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;

import prefuse.Constants;
import prefuse.render.PolygonRenderer;
import prefuse.visual.VisualItem;

/**
 * In the float[] array, we use duplicated points to indicate that point is a
 * sharp turn. So we detect those duplicated, and make them sharp.
 * 
 * Basically, we draw a line between the first and second duplicated points,
 * between the third and the forth duplicated points, etc.
 * @author weeny
 */
public class StreamRenderer extends PolygonRenderer{
	private float[] fa = new float[6];
	private GeneralPath m_gp = new GeneralPath();
	/**
	 * By default, we show them as curves
	 */
	public StreamRenderer() {
		super(Constants.POLY_TYPE_CURVE);
	}
	@Override
	public Shape getRawShape(VisualItem item) {
		m_gp.reset();
		boolean duplicated = false;
		GeneralPath tmp = (GeneralPath) super.getRawShape(item);
		for (PathIterator pi = tmp.getPathIterator(null); !pi.isDone();){
			duplicated = false;
			int type = pi.currentSegment(fa);
			switch (type) {
			case PathIterator.SEG_MOVETO:
				m_gp.moveTo(fa[0], fa[1]);
				break;
			case PathIterator.SEG_LINETO:
				m_gp.lineTo(fa[0], fa[1]);
				break;
			case PathIterator.SEG_QUADTO:
				if (fa[2] == m_gp.getCurrentPoint().getX() &&
					fa[3] == m_gp.getCurrentPoint().getY()){
					duplicated = true;
				}
				else {
					if (duplicated) {
						m_gp.lineTo(fa[2], fa[3]);
					}
					else{
						m_gp.quadTo(fa[0], fa[1], fa[2], fa[3]);
					}
					duplicated = false;
				}
				break;
			case PathIterator.SEG_CUBICTO:
				if (fa[4] == m_gp.getCurrentPoint().getX() &&
					fa[5] == m_gp.getCurrentPoint().getY()){
					duplicated = true;
				}
				else {
					if (duplicated) {
						m_gp.lineTo(fa[4], fa[5]);
					}
					else{
						m_gp.curveTo(fa[0], fa[1], fa[2], fa[3], fa[4], fa[5]);
					}
					duplicated = false;
				}
				break;
			case PathIterator.SEG_CLOSE:
				m_gp.closePath();
				break;
			default:
				break;
			}
			pi.next();
		}
		return m_gp;
	}
}
